package com.edu.exam.entity.grading;

import com.edu.exam.enums.common.StorageStatus;
import com.edu.exam.enums.common.StorageType;
import com.edu.exam.enums.common.ProcessResult;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 成绩临时存储实体类
 * 所属模块：B-06 成绩管理模块
 *
 * <p>成绩临时存储实体用于暂存成绩录入过程中的临时数据，包含
 * 临时数据管理、状态追踪、过期处理、清理机制等。确保数据录入过程的安全性和可靠性。</p>
 *
 * <p>核心功能：
 * - 临时存储：暂存未确认的成绩数据
 * - 状态管理：管理临时数据的状态和生命周期
 * - 过期控制：自动清理过期的临时数据
 * - 版本控制：支持数据版本管理和冲突检测
 * - 关联管理：管理与其他实体的关联关系</p>
 *
 * @author 系统生成
 * @version 1.0
 * @since 2025-11-10
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class GradeTempStorage {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 存储键
     *
     * <p>临时数据的唯一键值，用于标识和检索。</p>
     */
    @Column(name = "storage_key", nullable = false, length = 100, unique = true)
    private String storageKey;

    /**
     * 用户ID
     *
     * <p>创建临时数据的用户ID。</p>
     */
    @Column(name = "user_id", nullable = false, length = 50)
    private String userId;

    /**
     * 学生ID
     *
     * <p>关联学生的唯一标识符。</p>
     */
    @Column(name = "student_id", nullable = false, length = 50)
    private String studentId;

    /**
     * 课程ID
     *
     * <p>关联课程的唯一标识符。</p>
     */
    @Column(name = "course_id", nullable = false, length = 50)
    private String courseId;

    /**
     * 班级ID
     *
     * <p>关联的班级ID。</p>
     */
    @Column(name = "class_id", length = 50)
    private String classId;

    /**
     * 临时数据
     *
     * <p>存储的临时成绩数据，JSON格式。</p>
     */
    @Column(name = "temp_data", nullable = false, columnDefinition = "LONGTEXT")
    private String tempData;

    /**
     * 数据状态
     *
     * <p>临时数据的当前状态。
     * 支持的状态：ACTIVE（活跃）、LOCKED（锁定）、PENDING（待处理）、PROCESSING（处理中）、COMPLETED（已完成）、FAILED（失败）、EXPIRED（已过期）、DELETED（已删除）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private StorageStatus status = StorageStatus.ACTIVE;

    /**
     * 存储类型
     *
     * <p>临时数据的存储类型。
     * 支持的类型：DRAFT（草稿）、AUTO_SAVE（自动保存）、IMPORT_TEMP（导入临时）、VALIDATION_TEMP（验证临时）、CALCULATION_TEMP（计算临时）、BACKUP_TEMP（备份临时）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "storage_type", nullable = false, length = 30)
    private StorageType storageType = StorageType.DRAFT;

    /**
     * 过期时间
     *
     * <p>临时数据的过期时间，超过此时间自动清理。</p>
     */
    @Column(name = "expire_time", nullable = false)
    private LocalDateTime expireTime;

    /**
     * 会话ID
     *
     * <p>关联的用户会话ID。</p>
     */
    @Column(name = "session_id", length = 100)
    private String sessionId;

    /**
     * 批次ID
     *
     * <p>批量操作的批次标识符。</p>
     */
    @Column(name = "batch_id", length = 100)
    private String batchId;

    /**
     * 任务ID
     *
     * <p>关联的任务ID。</p>
     */
    @Column(name = "task_id", length = 50)
    private String taskId;

    /**
     * 父存储ID
     *
     * <p>父级临时存储的ID，用于层次结构。</p>
     */
    @Column(name = "parent_storage_id")
    private Long parentStorageId;

    /**
     * 目标实体ID
     *
     * <p>转换后目标实体的ID。</p>
     */
    @Column(name = "target_entity_id")
    private Long targetEntityId;

    /**
     * 目标实体类型
     *
     * <p>转换后目标实体的类型。</p>
     */
    @Column(name = "target_entity_type", length = 100)
    private String targetEntityType;

    /**
     * 数据版本
     *
     * <p>临时数据的版本号。</p>
     */
    @Column(name = "data_version", length = 20)
    private String dataVersion = "1.0";

    /**
     * 数据大小
     *
     * <p>临时数据的字节大小。</p>
     */
    @Column(name = "data_size_bytes")
    private Long dataSizeBytes;

    /**
     * 压缩标志
     *
     * <p>数据是否已压缩。</p>
     */
    @Column(name = "is_compressed", nullable = false)
    private Boolean isCompressed = false;

    /**
     * 加密标志
     *
     * <p>敏感数据是否已加密。</p>
     */
    @Column(name = "is_encrypted", nullable = false)
    private Boolean isEncrypted = false;

    /**
     * 访问次数
     *
     * <p>临时数据被访问的次数。</p>
     */
    @Column(name = "access_count", nullable = false)
    private Integer accessCount = 0;

    /**
     * 最后访问时间
     *
     * <p>临时数据最后被访问的时间。</p>
     */
    @Column(name = "last_access_time")
    private LocalDateTime lastAccessTime;

    /**
     * 锁定时间
     *
     * <p>数据被锁定的时间。</p>
     */
    @Column(name = "lock_time")
    private LocalDateTime lockTime;

    /**
     * 锁定用户ID
     *
     * <p>锁定数据的用户ID。</p>
     */
    @Column(name = "lock_user_id", length = 50)
    private String lockUserId;

    /**
     * 锁定原因
     *
     * <p>数据锁定的原因。</p>
     */
    @Column(name = "lock_reason", length = 500)
    private String lockReason;

    /**
     * 处理时间
     *
     * <p>数据处理的时间。</p>
     */
    @Column(name = "process_time")
    private LocalDateTime processTime;

    /**
     * 处理结果
     *
     * <p>数据处理的执行结果。
     * 支持的结果：SUCCESS（成功）、FAILED（失败）、PARTIAL（部分成功）、TIMEOUT（超时）、CANCELLED（取消）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "process_result", length = 20)
    private ProcessResult processResult;

    /**
     * 错误信息
     *
     * <p>处理失败时的错误信息。</p>
     */
    @Column(name = "error_message", columnDefinition = "TEXT")
    private String errorMessage;

    /**
     * 重试次数
     *
     * <p>处理失败的重试次数。</p>
     */
    @Column(name = "retry_count", nullable = false)
    private Integer retryCount = 0;

    /**
     * 最大重试次数
     *
     * <p>允许的最大重试次数。</p>
     */
    @Column(name = "max_retry_count")
    private Integer maxRetryCount = 3;

    /**
     * 下次重试时间
     *
     * <p>下次重试的时间。</p>
     */
    @Column(name = "next_retry_time")
    private LocalDateTime nextRetryTime;

    /**
     * 优先级
     *
     * <p>处理的优先级，数值越小优先级越高。</p>
     */
    @Column(name = "priority")
    private Integer priority = 0;

    /**
     * 标签
     *
     * <p>JSON格式的标签，用于分类和过滤。</p>
     */
    @Column(name = "tags", columnDefinition = "TEXT")
    private String tags;

    /**
     * 备注
     *
     * <p>临时数据的备注信息。</p>
     */
    @Column(name = "notes", columnDefinition = "TEXT")
    private String notes;

    /**
     * 元数据
     *
     * <p>JSON格式的元数据信息。</p>
     */
    @Column(name = "metadata", columnDefinition = "TEXT")
    private String metadata;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    /**
     * 创建用户ID
     */
    @Column(name = "create_user_id", length = 50)
    private String createUserId;

    /**
     * 更新用户ID
     */
    @Column(name = "update_user_id", length = 50)
    private String updateUserId;

    /**
     * 是否删除
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;

    /**
     * 删除时间
     */
    @Column(name = "delete_time")
    private LocalDateTime deleteTime;

    /**
     * 删除用户ID
     */
    @Column(name = "delete_user_id", length = 50)
    private String deleteUserId;}
